package demo5;

//import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/*
    Spring框架提供的注解
    @Component : 被该注解标注的类会被Spring容器管理
    @Controller: 被该注解标注的类也受Spring容器管理，该注解在SpringMVC框架中发挥作用，为标注了该注解的
                 类提供其他额外功能。注:Controller控制器层，主要负责衔接客户与业务层。
    @Service   : 被该注解标注的类受Spring容器管理，通常标注那些业务层的类
    @Repository: 被该注解标注的类受Spring容器管理,通常标注那些持久层的类
 */
@Component
//@Controller
//@Service
//@Repository
public class Person {
//    @Autowired
    /*
        Spring处理自身提供的注解外,也支持一些java原生注解
        例如:
        @Resource注解,这个注解原本在javax包中,但是在JDK17中已经被移除了.
        所以实际开发中还是推荐使用Spring自己提供的注解
     */
    /*
     * @Autowired 自动装配注解
     * Spring中的开发模式里,当A类需要使用B类的功能时,应当将B类作为属性定义在A类中.当然这里最好定义的是
     * 接口类型,以便日后可以随时更换为C类,D类..等等(B,C,D...这些类都实现类该接口).
     * 这种将A类依赖的B类定义为属性,让Spring容器将这个依赖的B类通过属性设置到A类中建立A与B的依赖关系,
     * 这个过程称为[依赖注入],意思是将A类"依赖"的B类通过属性"注入"给A类.
     *
     *
     *
     * Spring框架支持java原生提供的@Resource注解,用作依赖注入.
     * @Resource注解默认的装配机制与@Autowired一致,依靠类型匹配.
     *          首先在容器内部寻找该属性的类型,看看是否存在,若存在则直接装配
     *          如果不存在,查看是否有该属性类型的子类型,如果有将其装配.如果存在多个子类型则抛出冲突异常
     *          NoUniqueBeanDefinitionException: No qualifying bean of type 'demo5.Clothes' available: expected single matching bean but found 2: shirt,sweater
     *
     * @Resource注解解决装配冲突的几种操作:
     *      1:@Resource(name="类名")
     *        通过向@Resource注解中传入name参数,参数值为要加载的类的类名来让Spring容器完成依赖注入
     *        需要注意:这里虽然是类名,但是[首字母要小写]
     *        @Resource(name="shirt")   注入Shirt这个类
     *        @Resource(name="sweater") 注入Sweater这个类
     *        缺点:限制了依赖的类的类名.
     *
     *      2:要求属性的名字与类名一致
     *        @Resource
     *        private Clothes shirt;    注入Shirt这个类
     *
     *        @Resource
     *        private Clothes sweater;  注入Sweater这个类
     *
     * @Resource整体看可选择的注入方式多,但是解决装配冲突问题时缺点相同--限制依赖方类的名字
     *
     * @Resource实际开发中用的很少,基本上在Spring容器中使用的装配注解还是:@Autowired
     */
//    @Resource
//    @Resource(name="shirt")
//    @Resource(name="sweater")
//    private Clothes clothes;

    @Resource
//    private Clothes shirt;
    private Clothes sweater;
    public void play(){
//        clothes.wear();
//        shirt.wear();
        sweater.wear();
        System.out.println("出去玩");
    }
}
